package com.helloandroid.tools

import android.app.Activity
import android.view.View
import android.view.WindowManager
import android.widget.TextView
import com.helloandroid.AppUtil
import com.helloandroid.ServerConfig
import com.helloandroid.ext.tryGetInt
import com.helloandroid.ext.tryGetString
import game.engine.base.CoreUtil
import kotlinx.coroutines.*
import org.json.JSONObject
import java.lang.Exception
import kotlin.math.max
import kotlin.math.min
import kotlin.math.round

// app configs
object AppConfig{

    const val isDebug = false

    // 只有在 isDebug 为true的时候 才发挥作用
    const val IgnoreServerConfig = false
    const val isGM = false

    var isFake = false
    const val AdToggle = true

    //-------------------------
    // actions
//    const val Action_CoinOrMoney_Changed = "com.action.chg.coin_money"
    const val Action_GmCommond = "com.action.gm.command"
    const val Action_User_BindWx = "com.user.bindwx"

    //-----------------------
    // 玩家 id wx_id
    const val Pref_User = "userfile"
    const val KeyUserId = "user_id"
    const val KeyWxId = "wx_id"

    //------------------------
    // 通知设置
    // 一些用于本地判断的
    const val Pref_Local = "notify_local"  //
    const val KeyLastToastTime = "key_last_toast_time" // 首次登陆时间
    const val KeyToastCount = "key_toast_count" // 弹的总次数,最大次数为3
    const val KeyBsCompletionReport = "key_bs_completion_report" // 上报步数完成

    const val KeyNewUserToastFlag = "key_newuser_toast_flag" // 新用户弹框

    private val SignAwardArray = intArrayOf(58, 68, 68, 88, 88, 88, 108)

    // 成语过关 奖励18金币.
    const val CyCoinAwardPerLevel = 18

    // 返回签到的奖励金币
    fun getSignAwardCount(signedCount: Int):Int{
        val idx  = signedCount % SignAwardArray.size
        return SignAwardArray[idx]
    }
}

object GUtils {

    // 仪表盘是否已经动画了. 只播放一次
    var dashBoardAnimated = false

    const val KeyErr = "err"
    const val KeyData = "data"
    const val KeyTime = "serverTime"
    const val KeyMsg = "msg"

    const val OneMinutes = 60 * 1000
    const val TenMinutes = 10 * OneMinutes
    const val OneHourMs = 3600 * 1000
    const val TwoHourMs = 7200 * 1000
    const val OneDayMs = 24 * 3600 * 1000

    // 每步 0.52m
    const val MeterPerBu = 0.52f

    // money转换成coin
    fun moneyToReadableString(money: Int) = String.format("%.2f", money / 10000f)

//    private var __gsonInstance: Gson? = null
//    fun getGson(): Gson {
//        if (__gsonInstance == null) {
//            __gsonInstance = GsonBuilder().registerTypeAdapter<MatchType> {
//                serialize {
//                    JsonPrimitive(it.src.value)
//                }
//                deserialize {
//                    when (val value = it.json.asInt) {
//                        1 -> MatchType.M3000
//                        2 -> MatchType.M8000
//                        else -> throw RuntimeException("unknow value:$value")
//                    }
//                }
//            }
//                    .registerTypeAdapter<UserMatchState> {
//                serialize {
//                    JsonPrimitive(it.src.value)
//                }
//                deserialize {
//                    when (val value = it.json.asInt) {
//                        0 -> UserMatchState.TakePart
//                        1 -> UserMatchState.Moving
//                        2 -> UserMatchState.UnComplete
//                        3 -> UserMatchState.Completed
//                        4 -> UserMatchState.Geted
//                        else -> throw RuntimeException("unknow value:$value")
//                    }
//                }
//            }
//                    .registerTypeAdapter<MatchState> {
//                serialize {
//                    JsonPrimitive(it.src.value)
//                }
//                deserialize {
//                    when (val value = it.json.asInt) {
//                        1 -> MatchState.Unstarted
//                        2 -> MatchState.Running
//                        3 -> MatchState.Ended
//                        else -> throw RuntimeException("unknow value:$value")
//                    }
//                }
//            }
////                    .registerTypeAdapter<User>{
////                        deserialize {
////                            it.json.as
////                        }
////                    }
//                    .create()
//        }
//        return __gsonInstance!!
//    }


    /**
     * 测量 view 的宽高
     */
    @JvmStatic
    fun measureViewSize(view: View):Pair<Int, Int>{
        val w = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)
        val h = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)
        view.measure(w, h)
        val height: Int = view.measuredHeight
        val width: Int = view.measuredWidth
        return width to height
    }

    // 返回  [min,max]
    fun randomInt(min: Int, max: Int) = (Math.random() * (max - min + 1)).toInt() + min

    fun clampInt(value: Int, left: Int, right: Int) = min(max(left, value), right)
    fun clamp01(value: Float) = min(max(0f, value), 1f)

    @JvmStatic
    fun setStatusBarColor(activity: Activity, colorId: Int) {
        val window = activity.window
        window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
        window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
        window.statusBarColor = activity.resources.getColor(colorId, null)
    }

    @JvmStatic
    fun spToPx( spValue:Float):Int {
        val fontScale = AppUtil.dm.scaledDensity;
        return (spValue * fontScale + 0.5f).toInt()
    }

    fun coinToPrecision2Money(coin:Int):Float{
        return  if (coin in 1..100){
            0.01f
        }else{
            round(coin / 100f) / 100f
        }
    }

    fun parserServerConfig(jsonStr: String): ServerConfig {
        try {
            val jsonObj = JSONObject(jsonStr)
            val ignoreVersion = jsonObj.tryGetString("ignoreVersion")
            val hbyMax1Day = jsonObj.tryGetInt("hbyMax1Day")
            val txVideo = jsonObj.tryGetInt("txVideo")
            val myPageNativeAds = jsonObj.tryGetInt("myPageNativeAds")
            val zzPageNativeAds = jsonObj.tryGetInt("zzPageNativeAds")
            val newUserRedVideo = jsonObj.tryGetInt("newUserRedVideo")
            val dashboardDailyRedPacketVideo = jsonObj.tryGetInt("dashboardDailyRedPacketVideo")
            val giveupDoubleRewardDelay = jsonObj.tryGetInt("giveupDoubleRewardDelay")
            val dailySignVideo = jsonObj.tryGetInt("dailySignVideo")
            return ServerConfig(
                    ignoreVersion = ignoreVersion,
                    hbyMax1Day = hbyMax1Day,
                    txVideo = txVideo,
                    myPageNativeAds = myPageNativeAds,
                    zzPageNativeAds = zzPageNativeAds,
                    newUserRedVideo = newUserRedVideo,
                    dashboardDailyRedPacketVideo = dashboardDailyRedPacketVideo,
                    giveupDoubleRewardDelay = giveupDoubleRewardDelay,
                    dailySignVideo = dailySignVideo
            )
        } catch (ex: Exception) {
            ex.printStackTrace()
            MyLog.error("===============解析 jsonStr:$jsonStr 错误!")

            // 使用默认配置
            return ServerConfig.DefaultServerConfig
        }
    }
    fun randomAwardString():String{
        val value = CoreUtil.randomInt(0,99)
        return when{
            value >= 95 -> "10.0元"
            value >= 90 -> "2.0元"
            value >= 75 -> "1.0元"
            value >= 40 -> "0.5元"
            else -> "0.3元"
        }
    }

    suspend fun CoroutineScope.httpWithTimeOut(timeMs:Long, doHttpReq:suspend ()->String,callback:(String)->Unit){
        var bTimeOut = false
        var timeOutJob = launch {
            delay(timeMs)
            withContext(Dispatchers.Main){
                bTimeOut = true
                MyLog.info("=====超时....")
                callback("")
            }
        }
        launch {
            val str = doHttpReq()
            withContext(Dispatchers.Main){
                if (!bTimeOut){
                    timeOutJob.cancelAndJoin()
                    callback(str)
                }
            }
        }
    }


    fun updateDistanceAndEnergyUI(bs:Int,tvDistance:TextView,tvSpendTime:TextView,tvEnergy:TextView){
        // 每步 0.52m
        // 每秒 1.66步
        // 每步 消耗 0.03千卡
        tvDistance.text = String.format("%.2f", bs * GUtils.MeterPerBu / 1000f)

        // 超过1个小时,就使用  18sp
        val timeSeconds = (bs / 1.66f).toLong()
        if (timeSeconds < 3600) {
            tvSpendTime.text = MyTimeUtils.format_mmss(timeSeconds * 1000)
        } else {
            tvSpendTime.text = MyTimeUtils.format_HHmmss(timeSeconds * 1000)
        }

        // 卡路里
        tvEnergy.text = String.format("%.2f", bs * 0.03f)
    }

}